﻿using System;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using HPAGMRestAPIWrapper;

namespace AGMRestAPITest
{
    /// <summary>
    /// Summary description for AGMDefectTest
    /// </summary>
    [TestClass]
    public class AGMDefectTest
    {
        public AGMDefectTest()
        {
            //
            // TODO: Add constructor logic here
            //
        }

        private TestContext _testContextInstance;

        private static AGMConnection _connection;
        private static AGMDefects _bugs;

        private AGMDefect _addedBug;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return _testContextInstance;
            }
            set
            {
                _testContextInstance = value;
            }
        }

        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        [ClassInitialize]
        public static void MyClassInitialize(TestContext testContext)
        {
            _connection = new AGMConnection(AGMSetting.SERVERNAME, AGMSetting.USERNAME, AGMSetting.PASSWORD);
            _bugs = new AGMDefects(_connection);
        }
        
        //
        // Use ClassCleanup to run code after all tests in a class have run
        [ClassCleanup]
        public static void MyClassCleanup()
        {
            if (_connection != null)
                _connection.Logoff();
        }
        
        //
        // Use TestInitialize to run code before running each test 
        [TestInitialize]
        public void MyTestInitialize()
        {
            var fields = new Dictionary<string, string> {{"Summary", "Test Defect New"}, {"Severity", "1-Low"}};
            _addedBug = _bugs.Create(fields);
            
            Assert.IsTrue(_bugs.IsExists(_addedBug.Id.Value), "Create defect failed.");
            #endregion
        }
        
        //
        // Use TestCleanup to run code after each test has run
        [TestCleanup]
        public void MyTestCleanup()
        {
            _addedBug.Delete();
            Assert.IsTrue(!_bugs.IsExists(_addedBug.Id.Value), "delete defect fail.");
        }
        
        [TestMethod]
        public void Defect_Update()
        {
            _addedBug.SetUpdateField("Description", "Description of Defect");
            AGMDefect updBug = _addedBug.Update();
            Assert.AreEqual(updBug.GetField("Description").Value, "Description of Defect", "Update defect failed.");
        }

        [TestMethod]
        public void Defect_OpenFixRejectReopenClose()
        {
            AGMDefect openbug = _addedBug.Open();
            Assert.AreEqual(openbug.GetField("Status").Value, "Open", "Open defect failed.");

            AGMDefect fixbug = _addedBug.Fix();
            Assert.AreEqual(fixbug.GetField("Status").Value, "Fixed", "Fix defect failed.");

            AGMDefect rejectbug = _addedBug.Reject();
            Assert.AreEqual(rejectbug.GetField("Status").Value, "Rejected", "Reject defect failed.");

            AGMDefect reopenbug = _addedBug.Reopen();
            Assert.AreEqual(reopenbug.GetField("Status").Value, "Reopen", "Reopen defect failed.");

            AGMDefect closebug = _addedBug.Close();
            Assert.AreEqual(closebug.GetField("Status").Value, "Closed", "Close defect failed.");
        }

        [TestMethod]
        public void Defect_SingleSearch()
        {
            var fields = new Dictionary<string, string> {{"Detected By", "steve"}};

            var bugresults = _bugs.Search(fields);

            foreach (var bug in bugresults)
            {
                Assert.AreEqual(bug.GetField("Detected By").Value, "steve", "Search result incorrect.");
            }
        }

        [TestMethod]
        public void Defect_SearchByDate()
        {
            var fields = new Dictionary<string, string>
                             {
                                 {
                                     "creation-time",
                                     string.Format(@">={0} AND <={1}", DateTime.UtcNow.ToString("yyyy-MM-dd"),
                                                   DateTime.UtcNow.AddDays(1).ToString("yyyy-MM-dd"))
                                     }
                             };

            var bugresults = _bugs.Search(fields);
            Assert.AreEqual(bugresults.Count, 1, "Search result incorrect.");

            foreach (var bug in bugresults)
            {
                Assert.AreEqual(bug.GetField("Detected By").Value, "steve", "Search result incorrect.");
            }
        }

        [TestMethod]
        public void Defect_UploadDownLoadDeleteAttachment()
        {
            _addedBug.UploadAttachment(@"Test.txt");
            Assert.IsTrue(_addedBug.IsAttachmentExists("Test.txt"), "Uploaded attachement is not exists.");

            _addedBug.DownloadAttachment(@"Test.txt", @"c:\Test.txt");
            Assert.IsTrue(Helper.CheckAttachment(@"C:\Test.txt"), "Downloaded attachement is not exists.");

            _addedBug.DeleteAttachment(@"Test.txt");
            Assert.IsFalse(_addedBug.IsAttachmentExists("Test.txt"), "Uploaded attachement is not exists.");
        }

        [TestMethod]
        public void Defect_GetAddDeleteDefectLinks()
        {
            #region create some defects
            var fields = new Dictionary<string, string> {{"Summary", "New Defect 1"}, {"Severity", "1-Low"}};
            var newd1 = _bugs.Create(fields);
            #endregion

            _addedBug.LinkToDefects(new[] { newd1.Id.Value });
            var linkedbugs = _addedBug.GetLinkedDefects();
            foreach (var bug in linkedbugs)
            {
                Assert.IsTrue((bug.Id.Value == newd1.Id.Value), "Added defect link does not found.");
            }

            _addedBug.DeleteDefectLinks(new[] { newd1.Id.Value });
            var linkedbugs2 = _addedBug.GetLinkedDefects();
            Assert.AreEqual(linkedbugs2.Count, 0, "Delete defect links fail.");

            newd1.Delete();
        }

        [TestMethod]
        public void Defect_GetAddDeleteRequirementLinks()
        {
            #region add requirement item
            var reqs = new AGMRequirements(_connection);
            var fields = new Dictionary<string, string>
                             {
                                 {"Name", "New Requirement"},
                                 {"Description", "Description of new requirement."}
                             };
            var newReq = reqs.Create(fields);
            #endregion

            _addedBug.LinkToRequirements(new[] { newReq.Id.Value });
            var linkedreqs = _addedBug.GetLinkedRequirements();
            foreach (var req in linkedreqs)
            {
                Assert.IsTrue((req.Id.Value == newReq.Id.Value), "Added requirement link does not found.");
            }

            _addedBug.DeleteRequirementLinks(new[] { newReq.Id.Value });
            var linkedreqs2 = _addedBug.GetLinkedRequirements();
            Assert.AreEqual(linkedreqs2.Count, 0, "Delete requirement links fail.");

            newReq.Delete();
        }
    }
}
